<!DOCTYPE html>
<html lang="en">
 <head> 
  <meta charset="utf-8" /> 
  <title>js\utils.js</title> 
  <link rel="stylesheet" href="http://yui.yahooapis.com/3.8.0pr2/build/cssgrids/cssgrids-min.css" /> 
  <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css" /> 
  <link rel="stylesheet" href="../assets/css/main.css" id="site_styles" />  
  <script src="http://yui.yahooapis.com/combo?3.8.0pr2/build/yui/yui-min.js"></script> 
 </head> 
 <body class="yui3-skin-sam"> 
  <div id="doc"> 
   <div class="header"> 
    <a href="/"> 
     <div class="logo"> 
      <h3>RunJS</h3> 
     </div> </a> 
    <div class="headerMenu"> 
     <div class="menuItem btnGroup login"></div> 
    </div> 
   </div> 
   <div id="bd" class="yui3-g"> 
    <div class="yui3-u-1-4"> 
     <div id="docs-sidebar" class="sidebar apidocs"> 
      <div id="api-list"> 
       <h2 class="off-left">APIs</h2> 
       <div id="api-tabview" class="tabview"> 
        <ul class="tabs"> 
         <li><a href="#api-classes">Classes</a></li> 
         <li><a href="#api-modules">Modules</a></li> 
        </ul> 
        <div id="api-tabview-filter"> 
         <input type="search" id="api-filter" placeholder="Type to filter APIs" /> 
        </div> 
        <div id="api-tabview-panel"> 
         <ul id="api-classes" class="apis classes"> 
          <li><a href="../classes/Dialog.html">Dialog</a></li> 
          <li><a href="../classes/Editor.html">Editor</a></li> 
          <li><a href="../classes/Explorer.html">Explorer</a></li> 
          <li><a href="../classes/Global_Variables.html">Global_Variables</a></li> 
          <li><a href="../classes/Menu.html">Menu</a></li> 
          <li><a href="../classes/onEvents.html">onEvents</a></li> 
          <li><a href="../classes/Plugin.html">Plugin</a></li> 
          <li><a href="../classes/Plugins.html">Plugins</a></li> 
          <li><a href="../classes/Resource.html">Resource</a></li> 
          <li><a href="../classes/RunJS.html">RunJS</a></li> 
          <li><a href="../classes/Utils.html">Utils</a></li> 
         </ul> 
         <ul id="api-modules" class="apis modules"> 
         </ul> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
    <div class="yui3-u-3-4"> 
     <div id="api-options">
       Show: 
      <label for="api-show-inherited"> <input type="checkbox" id="api-show-inherited" checked="" /> Inherited </label> 
      <label for="api-show-protected"> <input type="checkbox" id="api-show-protected" /> Protected </label> 
      <label for="api-show-private"> <input type="checkbox" id="api-show-private" /> Private </label> 
      <label for="api-show-deprecated"> <input type="checkbox" id="api-show-deprecated" /> Deprecated </label> 
     </div> 
     <div class="apidocs"> 
      <div id="docs-main"> 
       <div class="content"> 
        <h1 class="file-heading">File: js\utils.js</h1> 
        <div class="file"> 
         <pre class="code prettyprint linenums">
/**
 * 模块工具类，用来初始化各模块视图、自定绑定事件以及其他辅助功能等
 * @class Utils
 */
Utils = (function() {

	var instance;

	/**
	 * @class Utils
	 * @constructor
	 */
	function Utils() {
		instance = this;
		return this;
	}

	/**
	 * 事件自动绑定 events:&lt;br&gt; 
	 * 事件映射列表 映射规则：&lt;br&gt;
	 * &quot;event(事件) -&gt; selector(选择器)&quot;:&quot;handler(事件处理器)&quot;&lt;br&gt;
	 * events = { &lt;br&gt;
	 * 		&quot;click-&gt;[document]&quot;:&quot;doc_click_handler&quot; &lt;br&gt;
	 * }&lt;br&gt;
	 * &lt;span style=&quot;color:#A00&quot;&gt;[注]&lt;/span&gt;如果selector带有中括号[]则表明为系统全局变量，如window,document&lt;br&gt;
	 * 需要以 call(module) 的方式把上下文设置成当前的模块实例
	 * @example
	 * 	g_utils.binder.call(module)
	 * @method binder
	 */
	Utils.prototype.binder = function() {
		var cur = this;
		var events = this.Events;
		if (isEmpty(events))
			return;
		var clazz = className(this);
		if (isEmpty(clazz))
			this.clazz = clazz = &quot;Plugin&quot;;
		Console.log(&quot;[&quot; + clazz + &quot;]Binding events&quot;);
		try {
			$.each(events, function(key, handler) {
				if (isEmpty(events))
					return;

				var handler = events[key];
				if (isEmpty(key))
					return;

				var sp = key.split(&quot;-&gt;&quot;);
				var evt = sp[0];
				var sel = sp[1];
				if (isEmpty(evt) || isEmpty(sel) || isNotFunc(cur[handler]) &amp;&amp; isNotFunc(handler))
					return;
				var one = function(event) {
					if (isNotFunc(handler)) {
						cur[handler].call(this, cur, event);
					} else {
						handler.call(this, cur, event)
					}
				};
				var hasWindowObj = sel.indexOf(&quot;[window]&quot;) != -1;
				var hasDocumentObj = sel.indexOf(&quot;[document]&quot;) != -1;
				if (hasWindowObj) {
					$(window).unbind(evt, one);
					$(window).bind(evt, one);
					sel = sel.replace(/[\[window\]]/g, &quot;&quot;)
				}

				if (hasDocumentObj) {
					$(document).unbind(evt, one);
					$(document).bind(evt, one);
					sel = sel.replace(/[\[document\]]/g, &quot;&quot;)
				}

				if (isEmpty(sel))
					return;

				Console.log(&quot;\t[&quot; + clazz + &quot;]Binding event[&quot; + handler + &quot;]&quot;);

				$(sel).die(evt).live(evt, one);

			})
		} catch (e) {
			Console.log(&quot;Error Occured When Binding Events:&quot; + e);
		}
	};

	/**
	 * 初始化参数：初始化arguments第一个参数（json格式），将其设置为当前对象的成员属性， params为json格式数据&lt;br&gt;
	 * @method initParams
	 * @example
	 * 	g_utils.initParams.call(module)
	 * @params {Object} params JSON类型数据
	 */
	Utils.prototype.initParams = function(params) {
		var clazz = className(this);
		if (isNotEmpty(params)) {
			Console.log(&quot;[&quot; + clazz + &quot;]Initializing Params with outer params&quot;);
			for ( var key in params) {
				this[key] = params[key];
			}
		}
		if (isNotEmpty(this.arg) &amp;&amp; isNotEmpty(this.arg[0])) {
			Console.log(&quot;[&quot; + clazz + &quot;]Initializing Params with arguments[0]&quot;);
			var opt = this.arg[0];
			for ( var key in opt) {
				if (isNotEmpty(opt[key]))
					this[key] = opt[key];
			}
		}
	};

	/**
	 * 初始化视图
	 * 自动像viewLink+&quot;/&quot;+ident路径请求模版，返回后插入到target中，初始化完成执行afterInit回调，并将当前对象当作调用上下文对象
	 * @method initParams
	 * @example
	 * 	g_utils.initView.call(module,ident,callback,async)
	 * @param {String} ident 代码的唯一标识
	 * @param {Function} afterInit 当视图初始化好后调用的回调函数
	 * @param {Boolean} async 是否采用异步方式加载数据，true或undefined时为异步方式，false为同步方式
	 */
	Utils.prototype.initView = function(ident, afterInit, async) {
		var cur = this;
		var clazz = className(this);
		var func = &quot;on&quot; + clazz + &quot;ViewInit&quot;;
		if (g_status.once) {
			afterInit.call(cur, ident, $(this.target).html());
			plugins.fireEvent(func, cur);
			return;
		}
		if (isEmpty(ident))
			ident = g_status.ident;
		Console.log(&quot;[&quot; + this.clazz + &quot;]Initializing View with ident:[&quot; + ident + &quot;] &quot; + (isFunc(afterInit) ? &quot;and callback&quot; : &quot;&quot;));
		var link = this.viewLink + &quot;/&quot; + ident + &quot;?&quot; + new Date().getTime();
		if (isEmpty(async) || async) {
			$.get(link, function(e) {
				cur.view = $(e);
				Console.log(&quot;[&quot; + cur.clazz + &quot;]View Loaded in async&quot;);
				if (isNotEmpty(cur.target) &amp;&amp; isNotEmpty(e)) {
					cur.target.html(e);
					afterInit.call(cur, ident, cur.view);
					plugins.fireEvent(func, cur);
				}
			});
		}else{
			var e = instance.load(link,async);
			cur.view = $(e);
			Console.log(&quot;[&quot; + cur.clazz + &quot;]View Loaded in syn&quot;);
			if (isNotEmpty(cur.target) &amp;&amp; isNotEmpty(e)) {
				cur.target.html(e);
				afterInit.call(cur, ident, cur.view);
				plugins.fireEvent(func, cur);
			}
		}
	};

	/**
	 * 采用同步或异步方式加载远端资源
	 * @method load
	 * @param {String} link 请求链接地址
	 * @param {Boolean} async 是否采用异步方式加载数据
	 * @param {Function} callback 采用异步方式的回调函数
	 * @param {Object} data 发送请求时附带参数数据
	 * @return {String} responseText 采用同步方式时直接返回结果，采用异步方式时将返回 undefined
	 */
	Utils.prototype.load = function(link, async, callback, data) {
		var cur = this;
		return $.ajax({
			url : link,
			success : function(html) {
				if (isFunc(callback))
					callback.call(cur, html);
			},
			data : data,
			async : async,
			type : &quot;post&quot;
		}).responseText;
	}

	/**
	 * 处理服务器端返回的JSON类型数据结果，判断是否为出错信息，并提供两种方式处理错误
	 * @method errorHandler
	 * @param {String} msg 服务器传来待处理的 JSON 格式字符串
	 * @param {Function} success 无错误时的回调函数，该回调将获得处理过后的 JSON 数据
	 * @param {Function} error 服务器端传来错误信息时调用，将返回出错 JSON 数据
	 * @param {Boolean} diy 是否立即使用 error 回调函数处理错误，true为立即使用error处理，false和undefined为系统使用弹窗显示错误然后再调用error回调处理
	 */
	Utils.prototype.errorHandler = function(msg, success, error, diy) {
		try {
			var msg = eval(&quot;(&quot; + msg + &quot;)&quot;);
			if (msg.error) {
				if (isEmpty(diy) || !diy) {
					dialog.get(&quot;error&quot;, msg.msg);
					if (typeof error != &quot;undefined&quot;) {
						setTimeout(function() {
							error(msg);
						}, 2000);
					}
					return false;
				} else {
					if (typeof error != &quot;undefined&quot;) {
						return error(msg);
					}
				}
			}
			return success(msg)
		} catch (e) {
			if (typeof e.stack != 'undefined') {
				dialog.get(&quot;jserror&quot;, e.stack.substring(0, 50));
			} else
				dialog.get(&quot;jserror&quot;, e.message);
			return;
		}
	}

	/**
	 * 阻止浏览器默认事件
	 * @method stopDefault
	 * @param {Object} event 浏览器事件对象
	 */
	Utils.prototype.stopDefault = function(event) {
		event.preventDefault();
		event.returnvalue = false;
	}

	/**
	 * 初始状态信息，该方法用来从服务器端加载一段js，用eval执行来初始化全局变量
	 * @method initStatus
	 * @param {String} link 请求链接地址
	 */
	Utils.prototype.initStatus = function(link) {
		var status = this.load(link, false);
		if (isNotEmpty(status))
			eval(status);
	}

	/**
	 * 获得以“http://”开头的链接地址，并加上当前域的HOST名称,例如 g_utils.getHttpLink(&quot;/code/abcdefg&quot;)将返回&quot;http://runjs.cn/code/abcdefg&quot;
	 * @method getHttpLink
	 * @return {String} link 返回处理好的链接地址
	 */
	Utils.prototype.getHttpLink = function(link) {
		if (isEmpty(link))
			return;
		if (link.indexOf(&quot;http&quot;) == -1) {
			if (link.indexOf(&quot;/&quot;) == 0) {
				link = g_status.host + link;
			} else {
				link = g_status.host + &quot;/&quot; + link;
			}
		}
		return link;
	}

	return Utils;
})();

/**
 * Utils 类实例[全局]
 * @attribute g_utils
 */
g_utils = new Utils();

/**
 * 判断当前对象是否为空
 * @method isEmpty
 * @param {Object} obj
 * @return {Boolean} empty 当为 null,undefined,&quot;&quot; 将返回true
 */
window.isEmpty = function(obj) {
	return (obj == null || typeof obj == &quot;undefined&quot; || obj.length == 0)
}

/**
 * 判断当前对象是否非空
 * @method isNotEmpty
 * @param {Object} obj
 * @return {Boolean}  
 */
window.isNotEmpty = function(obj) {
	return !isEmpty(obj);
}

/**
 * 判断是否为函数
 * @method isFunc
 * @param {Object} fun
 * @return {Boolean}
 */
window.isFunc = function(fun) {
	return (fun != null &amp;&amp; typeof fun == &quot;function&quot;);
}

/**
 * 判断不是函数
 * @method isNotFunc
 * @param {Object} fun
 * @return {Boolean}
 */
window.isNotFunc = function(fun) {
	return !isFunc(fun);
}

/**
 * 判断 cur 是否为 type 类型
 * @method typeOf
 * @param {Object} cur
 * @param {String} type
 * @example
 * 	typeOf(&quot;Hello&quot;,&quot;string&quot;);//将返回true
 * @return {Boolean}
 */
window.typeOf = function(cur, type) {
	if (typeof type != &quot;string&quot;)
		return false;
	return typeof cur == type;
}

/**
 * 判断是否为数组
 * @method isArray
 * @param {Object} array
 * @return {Boolean}
 */
window.isArray = function(array) {
	return isNotEmpty(array) &amp;&amp; className(array) == &quot;Array&quot;
}

/**
 * 判断不是数组
 * @method isNotArray
 * @param {Object} arr
 * @return {Boolean}
 */
window.isNotArray = function(arr) {
	return !isArray(arr);
}

/**
 * 获取当前模块名
 * @method className
 * @param {Object} obj
 * @example
 *  className(g_utils);//返回 &quot;Utils&quot;
 * @return
 */
window.className = function(obj) {
	if (obj &amp;&amp; obj.constructor &amp;&amp; obj.constructor.toString) {
		var arr = obj.constructor.toString().match(/function\s*(\w+)/);
		if (arr &amp;&amp; arr.length == 2) {
			obj.clazz = arr[1]
			return arr[1];
		}
	}
	return undefined;
}

/**
 * 判断两个对象是否为相同的类
 * @method isSameClass
 * @param {Object} cur
 * @param {Object} cur2
 * @return {Boolean}
 */
window.isSameClass = function(cur, cur2) {
	if (isNotEmpty(cur) &amp;&amp; isNotEmpty(cur2)) {
		return className(cur) == className(cur2);
	}
	return false;
}

/**
 * 判断两个对象为不同类
 * @method isDifClass
 * @param {Object} cur
 * @param {Object} cur2
 * @return {Boolean}
 */
window.isDifClass = function(cur, cur2) {
	return !isSameClass(cur, cur2);
}

/**
 * 以 window.open 方式打开弹窗
 * @method openwindow
 * @param {String} url
 * @param {String} name
 * @param {Number} iWidth
 * @param {Number} iHeight
 */
window.openwindow = function(url, name, iWidth, iHeight) {
	var url; // 转向网页的地址;
	var name; // 网页名称，可为空;
	var iWidth; // 弹出窗口的宽度;
	var iHeight; // 弹出窗口的高度;
	var iTop = (window.screen.availHeight - 30 - iHeight) / 2; // 获得窗口的垂直位置;
	var iLeft = (window.screen.availWidth - 10 - iWidth) / 2; // 获得窗口的水平位置;
	window.open(url, name, 'height=' + iHeight + ',,innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
}

/**
 * 返回 true 且啥也不处理的回调函数，用于{{#crossLink &quot;Dialog&quot;}}{{/crossLink}}中设置无所作为的按钮的事件
 * @method doNothing
 * @example
 * 	dialog.get(&quot;confrim2&quot;,doNothing,doNow);//doNow 为回调函数
 * @return {Boolean}
 */
window.doNothing = function() {
	return true;
}

/**
 * 更新浏览器地址栏链接地址
 * @method updateUrl
 * @param {String} url
 */
window.updateUrl = function(url) {
	if (window.history &amp;&amp; window.history.pushState) {
		window.history.pushState(null, url, url);
	}
};

/**
 * 判断当前是否处在iframe中
 * @method isIframe
 * @return {Boolean}
 */
window.isIframe = function() {
	return top.location != self.location;
}

/**
 * 判断当前不处在iframe中
 * @method isIframe
 * @return {Boolean}
 */
window.isNotIframe = function() {
	return !isIframe();
};

/**
 * 利用数组的join构造字符串，提高字符串拼接效率
 * @method buildString
 * @param arguments {String|Number}
 * @return {String} 拼接后的字符串
 */
window.buildString = function(){
	var str = [];
	for(var i=0;i&lt;arguments.length;i++){
		str[i] = arguments[i];
	}
	return str.join(&quot;&quot;);
};

window.console = window.console || {};

console.log || (console.log = typeof opera != &quot;undefined&quot; ? opera.postError : function(msg) {
});

/*---IE Extend---*/
if (!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(elt /* , from */) {
		var len = this.length &gt;&gt;&gt; 0;

		var from = Number(arguments[1]) || 0;
		from = (from &lt; 0) ? Math.ceil(from) : Math.floor(from);
		if (from &lt; 0)
			from += len;

		for (; from &lt; len; from++) {
			if (from in this &amp;&amp; this[from] === elt)
				return from;
		}
		return -1;
	};
}

ConsoleUtils = (function(){
	var open = false;
	function ConsoleUtils(op){
		open = op;
	}
	ConsoleUtils.prototype.toggle = function(){
		open = !open;
	};
	ConsoleUtils.prototype.open = function(){
		open = true;
	}
	ConsoleUtils.prototype.close = function(){
		open = false;
	}
	ConsoleUtils.prototype.log = function(msg){
		if(open)
			console.log(msg);
	}
	return ConsoleUtils;
})();

Console = new ConsoleUtils(false);

    </pre> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
   </div> 
  </div> 
  <script src="../assets/vendor/prettify/prettify-min.js"></script> 
  <script>prettyPrint();
  </script> 
  <script src="../assets/js/yui-prettify.js"></script> 
  <script src="../assets/../api.js"></script> 
  <script src="../assets/js/api-filter.js"></script> 
  <script src="../assets/js/api-list.js"></script> 
  <script src="../assets/js/api-search.js"></script> 
  <script src="../assets/js/apidocs.js"></script>   
  <script type="text/javascript">document.write('<link rel="stylesheet" href="/css/runjs_api.css" id="site_styles">');
  </script>
 </body>
</html>